﻿/*
 * This file is part of MonoStrategy.
 *
 * Copyright (C) 2010-2011 Christoph Husse
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: 
 *      # Christoph Husse
 * 
 * Also checkout our homepage: http://monostrategy.codeplex.com/
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MonoStrategy
{
    internal partial class TerrainRouting
    {
        private struct PathNodeKey : IQueueItem
        {
            internal int X;
            internal int Y;
            internal long Time;
            internal double G;
            internal double H;
            internal int Length;
            private double m_F;
            private int m_Index;

            public double F { get { return m_F; } set { m_F = value; } }
            public int Index { get { return m_Index; } set { m_Index = value; } }

            internal static KeyComparer Comparer = new KeyComparer();
            internal static KeyComparerIgnoreTime ComparerIgnoreTime = new KeyComparerIgnoreTime();
            private static readonly Stack<PathNodeKey> m_AllocationCache = new Stack<PathNodeKey>();

            internal class KeyComparer : IComparer<PathNodeKey>
            {
                public int Compare(PathNodeKey a, PathNodeKey b)
                {
                    if (a.X < b.X)
                        return -1;
                    else if (a.X > b.X)
                        return 1;

                    if (a.Y < b.Y)
                        return -1;
                    else if (a.Y > b.Y)
                        return 1;

                    // must be the last comparison
                    if (a.Time < b.Time)
                        return -1;
                    else if (a.Time > b.Time)
                        return 1;

                    return 0;
                }
            }

            internal class KeyComparerIgnoreTime : IComparer<PathNodeKey>
            {
                public int Compare(PathNodeKey a, PathNodeKey b)
                {
                    if (a.X < b.X)
                        return -1;
                    else if (a.X > b.X)
                        return 1;

                    if (a.Y < b.Y)
                        return -1;
                    else if (a.Y > b.Y)
                        return 1;

                    return 0;
                }
            }

            internal PathNodeKey(int inX, int inY, long inTime, int inLength)
            {
                Length = inLength;
                H = 0;
                G = 0;
                X = inX;
                Y = inY;
                Time = inTime;
                m_Index = -1;
                m_F = 0;
            }

            internal PathNodeKey(int inX, int inY, long inTime) : this(inX, inY, inTime, 0)
            {
            }

            public override string ToString()
            {
                return
                    "X: " + X.ToString().Padding(3) +
                    "; Y: " + Y.ToString().Padding(3) +
                    "; Time: " + Time.ToString().Padding(4) +
                    "; Length: " + Length.ToString().Padding(2);
            }
        }
    }
}
